package com.zhiyin.seal.controller;

import com.google.common.collect.Lists;
import com.zhiyin.seal.constant.SealResponseCodeConst;
import com.zhiyin.seal.entity.bo.*;
import com.zhiyin.seal.entity.dto.*;
import com.zhiyin.seal.entity.vo.*;
import com.zhiyin.seal.service.ApplyService;
import com.zhiyin.seal.service.FileService;
import com.zhiyin.seal.service.SealService;
import com.zhiyin.seal.util.BeanUtil;
import com.zhiyin.seal.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 用印申请控制器
 */
@RestController
@RequestMapping("/apply")
public class ApplyController {

    @Autowired
    ApplyService applyService;

    @Autowired
    SealService sealService;

    @Autowired
    FileService fileService;

    @PostMapping("/add")
    public ResponseDTO<Boolean> addUseSealApply(@RequestBody UseSealApplyDTO applyDTO){
        ApplyBo applyBo = BeanUtil.copy(applyDTO, ApplyBo.class);
        if(applyBo.getStampPhotograph() == null){
            applyBo.setStampPhotograph(false);
        }
        if(applyDTO.getFacePhoto() == null){
            applyDTO.setFacePhoto(true);
        }
        // 赋值拍照图片
        List<String> imgUrls = applyDTO.getImageUrls();
        applyBo.setImageUrls(imgUrls);
        // 赋值上传附件
        List<String> fileUrls = applyDTO.getFileUrls();
        applyBo.setFileUrls(fileUrls);
        // 赋值用印失效时间
        applyBo.setExpireTime(DateUtil.getDateFromString(applyDTO.getExpireTime()));
        // 判断印章过期时间
        SealBo sealBo = sealService.getSealByIdAndCompany(applyBo.getSealId(),applyBo.getCompanyId());
        if(sealBo.getServiceTime().getTime() - (new Date()).getTime() < 0){
            return ResponseDTO.wrap(SealResponseCodeConst.EXPIRE_SERVICE_TIME);
        }
        // 用印时间不能超过服务费时间
        if(sealBo.getServiceTime().getTime() - applyBo.getExpireTime().getTime() < 0){
            return ResponseDTO.wrap(SealResponseCodeConst.OUT_SERVICE_TIME);
        }

        return ResponseDTO.succData(applyService.addUseSealApply(applyBo));
    }

    @GetMapping("/info")
    public ResponseDTO<ApplyVo> getApplyInfo(@RequestParam("applyId") Long applyId){
        return ResponseDTO.succData(BeanUtil.copy(applyService.getApplyInfo(applyId),ApplyVo.class));
    }

    @GetMapping("/contracttypelist")
    public ResponseDTO<ContractTypeVo> getContractTypeList(){
        List<ContractTypeBo> contractTypeBoList = applyService.getContractTypeList();

        ContractTypeVo contractTypeVo = new ContractTypeVo();
        List<String> parentList = Lists.newArrayList();
        List<List<String>> childList = Lists.newArrayList();
        List<String> strArray = null;

        Long parentId = 0l;
        for (ContractTypeBo contractTypeBo : contractTypeBoList) {
            // 判断是否为合同大类
            if(contractTypeBo.getParentId() == 0l){
                parentList.add(contractTypeBo.getName());
            } else {
                if(contractTypeBo.getParentId() != parentId){
                    strArray = Lists.newArrayList();
                    strArray.add(contractTypeBo.getName());
                    childList.add(strArray);
                    parentId = contractTypeBo.getParentId();
                } else {
                    strArray.add(contractTypeBo.getName());
                }
            }
        }

        contractTypeVo.setParentList(parentList);
        contractTypeVo.setChildList(childList);

        return ResponseDTO.succData(contractTypeVo);
    }

    @GetMapping("/company/contract/list")
    public ResponseDTO<ContractTypeVo> getCompanyContractList(@RequestParam Long companyId){
        List<ContractTypeBo> contractTypeBoList = applyService.getCompanyContractList(companyId);

        ContractTypeVo contractTypeVo = new ContractTypeVo();
        List<String> parentList = Lists.newArrayList();
        List<List<String>> childList = Lists.newArrayList();
        List<String> strArray = null;

        Long parentId = 0l;
        for (ContractTypeBo contractTypeBo : contractTypeBoList) {
            // 判断是否为合同大类
            if(contractTypeBo.getParentId() == 0l){
                parentList.add(contractTypeBo.getName());
            } else {
                if(contractTypeBo.getParentId() != parentId){
                    strArray = Lists.newArrayList();
                    strArray.add(contractTypeBo.getName());
                    childList.add(strArray);
                    parentId = contractTypeBo.getParentId();
                } else {
                    strArray.add(contractTypeBo.getName());
                }
            }
        }

        contractTypeVo.setParentList(parentList);
        contractTypeVo.setChildList(childList);

        return ResponseDTO.succData(contractTypeVo);
    }

    @GetMapping("/available/list")
    public ResponseDTO<List<ApplyOfMyVo>> getAvailableApplyList(@RequestParam Long userId){
        List<ApplyOfMyBo> applyOfMyBoList = applyService.getAvailableApplyList(userId);
        if(applyOfMyBoList == null){
            return ResponseDTO.succData(Lists.newArrayList());
        }
        // 赋值单据印章实体
        List<ApplyOfMyVo> applyOfMyVoList = Lists.newArrayList();
        for (ApplyOfMyBo applyOfMyBo : applyOfMyBoList) {
            ApplyOfMyVo applyOfMyVo = BeanUtil.copy(applyOfMyBo, ApplyOfMyVo.class);
            applyOfMyVo.setSealInfo(BeanUtil.copy(applyOfMyBo.getSealInfo(),SealVo.class));

            applyOfMyVoList.add(applyOfMyVo);
        }

        return ResponseDTO.succData(applyOfMyVoList);
    }

    @PostMapping("/my/list")
    public ResponseDTO<List<ApplyOfMyVo>> getMyApplyList(@RequestBody ApplySearchParamsDTO paramsDTO){
        ApplySearchParamsBo paramsBo = buildApplySearchParamsBo(paramsDTO);
        List<ApplyOfMyBo> applyOfMyBoList = applyService.getMyApplyList(paramsBo);
        if(applyOfMyBoList == null){
            return ResponseDTO.succData(Lists.newArrayList());
        }
        // 赋值单据印章实体
        List<ApplyOfMyVo> applyOfMyVoList = Lists.newArrayList();
        for (ApplyOfMyBo applyOfMyBo : applyOfMyBoList) {
            ApplyOfMyVo applyOfMyVo = BeanUtil.copy(applyOfMyBo, ApplyOfMyVo.class);
            applyOfMyVo.setSealInfo(BeanUtil.copy(applyOfMyBo.getSealInfo(),SealVo.class));

            applyOfMyVoList.add(applyOfMyVo);
        }

        // 获取数据总数
        ResponseDTO responseDTO =  ResponseDTO.succData(applyOfMyVoList);
        responseDTO.setTotalCount(applyService.getMyApplyTotalCount(paramsBo));

        return responseDTO;
    }

    @PostMapping("/approval/list")
    public ResponseDTO<List<ApplyOfMyApprovalVo>> getMyApprovalList(@RequestBody ApplySearchParamsDTO paramsDTO){
        ApplySearchParamsBo paramsBo = buildApplySearchParamsBo(paramsDTO);
        List<ApplyOfMyApprovalBo> approvalBoList =  applyService.getMyApprovalList(paramsBo);
        if(approvalBoList == null){
            return ResponseDTO.succData(Lists.newArrayList());
        }
        // 赋值单据印章实体，用户实体
        List<ApplyOfMyApprovalVo> approvalVoList = Lists.newArrayList();
        for (ApplyOfMyApprovalBo approvalBo : approvalBoList) {
            ApplyOfMyApprovalVo approvalVo = BeanUtil.copy(approvalBo,ApplyOfMyApprovalVo.class);
            approvalVo.setSealInfo(BeanUtil.copy(approvalBo.getSealInfo(),SealVo.class));
            approvalVo.setUserInfo(BeanUtil.copy(approvalBo.getUserInfo(),UserVo.class));

            approvalVoList.add(approvalVo);
        }

        // 获取数据总数
        ResponseDTO responseDTO =  ResponseDTO.succData(approvalVoList);
        responseDTO.setTotalCount(applyService.getMyApprovalTotalCount(paramsBo));

        return responseDTO;
    }

    @PostMapping("/cc/list")
    public ResponseDTO<List<ApplyOfMyCCVo>> getMyCCList(@RequestBody ApplySearchParamsDTO paramsDTO){
        ApplySearchParamsBo paramsBo = buildApplySearchParamsBo(paramsDTO);
        List<ApplyOfMyCCBo> ccBoList = applyService.getMyCCList(paramsBo);
        if(ccBoList == null){
            return ResponseDTO.succData(Lists.newArrayList());
        }
        // 赋值单据印章实体，用户实体
        List<ApplyOfMyCCVo> ccVoList = Lists.newArrayList();
        for (ApplyOfMyCCBo ccBo : ccBoList) {
            ApplyOfMyCCVo ccVo = BeanUtil.copy(ccBo,ApplyOfMyCCVo.class);
            ccVo.setSealInfo(BeanUtil.copy(ccBo.getSealInfo(),SealVo.class));
            ccVo.setUserInfo(BeanUtil.copy(ccBo.getUserInfo(),UserVo.class));

            ccVoList.add(ccVo);
        }

        // 获取数据总数
        ResponseDTO responseDTO =  ResponseDTO.succData(ccVoList);
        responseDTO.setTotalCount(applyService.getMyCCTotalCount(paramsBo));

        return responseDTO;
    }

    @GetMapping("/replace")
    public ResponseDTO<Boolean> replaceApply(@RequestParam Long applyId,@RequestParam Long userId){
        return ResponseDTO.succData(applyService.replaceApply(applyId,userId));
    }

    @GetMapping("/revoke")
    public ResponseDTO<Boolean> revokeApply(@RequestParam Long applyId){
        return ResponseDTO.succData(applyService.revokeApply(applyId));
    }

    @PostMapping("/approval")
    public ResponseDTO<Boolean> approvalApply(@RequestBody ApprovalParamsDTO paramsDTO){
        return ResponseDTO.succData(applyService.approvalApply(BeanUtil.copy(paramsDTO,ApprovalParamsBo.class)));
    }

    @GetMapping("/close")
    public ResponseDTO<Boolean> closeApply(@RequestParam Long applyId){
        return ResponseDTO.succData(applyService.closeApply(applyId));
    }

    @GetMapping("/detail")
    public ResponseDTO<ApplyDetailVo> getApplyDetailInfo(@RequestParam Long applyId){
        ApplyDetailBo applyDetailBo = applyService.getApplyDetailInfo(applyId);
        ApplyDetailVo applyDetailVo = BeanUtil.copy(applyDetailBo,ApplyDetailVo.class);
        applyDetailVo.setSealInfo(BeanUtil.copy(applyDetailBo.getSealInfo(),SealVo.class));
        applyDetailVo.setApplyUserInfo(BeanUtil.copy(applyDetailBo.getApplyUserInfo(),UserVo.class));
        applyDetailVo.setStampUserInfo(BeanUtil.copy(applyDetailBo.getStampUserInfo(),UserVo.class));
        applyDetailVo.setCompanyInfo(BeanUtil.copy(applyDetailBo.getCompanyInfo(),CompanyVo.class));
        // 构造返回的审批流数据
        List<MyApprovalBo> myApprovalBoList = applyDetailBo.getApprovalList();
        List<MyApprovalVo> myApprovalVoList = Lists.newArrayList();
        for (MyApprovalBo myApprovalBo : myApprovalBoList) {
            MyApprovalVo myApprovalVo = BeanUtil.copy(myApprovalBo,MyApprovalVo.class);
            UserBo userBo = myApprovalBo.getUserInfo();
            myApprovalVo.setUserHeadPortrait(userBo.getAvatarUrl());
            myApprovalVo.setUserName(userBo.getNickName());
            myApprovalVo.setDisplay(myApprovalBo.getStatus() > 1 ? 1:0);
            myApprovalVoList.add(myApprovalVo);
        }

        List<MyCCBo> myCCBoList = applyDetailBo.getCcList();
        List<MyCCVo> myCCVoList = Lists.newArrayList();
        for (MyCCBo myCCBo : myCCBoList) {
            MyCCVo myCCVo = new MyCCVo();
            UserBo userBo = myCCBo.getUserInfo();
            myCCVo.setUserHeadPortrait(userBo.getAvatarUrl());
            myCCVo.setUserName(userBo.getNickName());
            myCCVo.setDisplay(1);
            myCCVoList.add(myCCVo);
        }

        applyDetailVo.setApprovalList(myApprovalVoList);
        applyDetailVo.setCcList(myCCVoList);
        // 申请拍照图片
        List<ApplyPhotoBo> applyPhotoBoList = applyService.getApplyImageList(applyId,1);
        if(applyPhotoBoList != null && applyPhotoBoList.size() > 0){
            List<String> imageUrls = Lists.newArrayList();
            for(int i=0; i < applyPhotoBoList.size(); i ++){
                ApplyPhotoBo applyPhotoBo = applyPhotoBoList.get(i);
                imageUrls.add(applyPhotoBo.getImageUrl());
            }
            applyDetailVo.setImageUrls(imageUrls);
        }
        // 上传附件
        List<ApplyAttachmentBo> attachmentBoList = fileService.getAttachmentListByApplyId(applyId);
        List<ApplyAttachmentVo> attachmentVoList = BeanUtil.copyList(attachmentBoList,ApplyAttachmentVo.class);
        applyDetailVo.setAttachmentList(attachmentVoList);

        return ResponseDTO.succData(applyDetailVo);
    }

    @GetMapping("/export")
    public void exportApply(@RequestParam Long applyId, HttpServletResponse response){
        ApplyDetailBo applyDetailBo = applyService.getApplyDetailInfo(applyId);
        fileService.exportApply(applyDetailBo,response);
    }

    @GetMapping("/hasmyapproval")
    public ResponseDTO<Boolean> getHasMyApproval(@RequestParam Long userId){
        return ResponseDTO.succData(applyService.getHasMyApproval(userId));
    }

    protected ApplySearchParamsBo buildApplySearchParamsBo(ApplySearchParamsDTO paramsDTO){
        ApplySearchParamsBo paramsBo = BeanUtil.copy(paramsDTO, ApplySearchParamsBo.class);
        if(paramsBo.getPageNo() == null){
            paramsBo.setPageNo(0);
        }
        if(paramsBo.getPageSize() == null){
            paramsBo.setPageSize(20);
        }
        if(paramsDTO.getWhetherWeb() != null && paramsDTO.getWhetherWeb()){
            paramsBo.setPageNo(paramsBo.getPageNo() -1);
        }
        // 计算查询截止日期
        if(paramsDTO.getDuration() != null){
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.add(Calendar.DAY_OF_MONTH,-paramsDTO.getDuration());
            paramsBo.setCreateTime(DateUtil.COMMON_DATE_FORMATE.format(calendar.getTime()));
        }

        return paramsBo;
    }
}